package com.mf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mf.enums.EnumDataDictionaryType;
import io.github.heollhai.common.basic.BasicKey;
import io.github.heollhai.common.config.security.utils.SecurityUtils;
import io.github.heollhai.common.entity.bo.RoleBo;
import io.github.heollhai.common.entity.security.dto.UserByRoleDto;
import io.github.heollhai.common.enums.EnableOrDisableEnum;
import io.github.heollhai.common.config.exceptions.GraceException;
import io.github.heollhai.common.utils.MybatisPlusUtils;
import io.github.heollhai.common.utils.VerifyUtils;
import io.github.heollhai.common.utils.enums.EnumUtils;
import io.github.heollhai.common.utils.tree.TreeUtils;
import com.mf.entity.bo.BasicDataDictionaryBo;
import com.mf.entity.request.searchParams.SearchDictionaryRequest;
import com.mf.entity.vo.BasicDataDictionaryVo;
import com.mf.mapper.BasicDataDictionaryMapper;

import com.mf.service.IBasicDataDictionaryService;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据字典 服务实现类
 *
 * @author mf
 * @since 2024-08-23
 */
@Service
@Slf4j
public class BasicDataDictionaryServiceImpl extends ServiceImpl<BasicDataDictionaryMapper, BasicDataDictionaryBo> implements IBasicDataDictionaryService {
    @Resource
    private BasicDataDictionaryMapper basicDataDictionaryMapper;

    @Override
    public Integer insert(BasicDataDictionaryVo basicDataDictionaryVo) {

        if (EnumUtils.existsInEnum(EnumDataDictionaryType.class, basicDataDictionaryVo.getType())) {
            GraceException.display("字典类型不存在");
        }


        BasicDataDictionaryBo basicDataDictionaryBo = new BasicDataDictionaryBo();
        BeanUtils.copyProperties(basicDataDictionaryVo, basicDataDictionaryBo);

        // 有父级查询对应父级数据并在子数据中写入父级code
        if (basicDataDictionaryBo.getPid() != 0) {
            BasicDataDictionaryBo dictionaryBo = getById(basicDataDictionaryBo.getPid());
            if (VerifyUtils.isEmpty(dictionaryBo)) {
                GraceException.display("没有对应添加的父级");
            }
            basicDataDictionaryBo.setPCode(dictionaryBo.getCode());
        } else {
            basicDataDictionaryBo.setPCode(null);
        }

        // 新增
        if (VerifyUtils.isEmpty(basicDataDictionaryVo.getId())) {
            // 如果code不为空，那么验证是否重复
            if (StringUtils.isNotEmpty(basicDataDictionaryVo.getCode())) {
                if (findByCode(basicDataDictionaryVo.getCode())) {
                    GraceException.display("字典编码重复");
                }
                ;
            }
            // 批量新增
            String[] split = basicDataDictionaryVo.getLabel().split(";");
            List<BasicDataDictionaryBo> basicDataDictionaryBos = new ArrayList<>();

            for (String label : split) {
                BasicDataDictionaryBo dataDictionaryBo = new BasicDataDictionaryBo();
                BeanUtils.copyProperties(basicDataDictionaryBo, dataDictionaryBo);
                dataDictionaryBo.setLabel(label);
                dataDictionaryBo.setStatus(EnableOrDisableEnum.ENABLE.value);
                basicDataDictionaryBos.add(dataDictionaryBo);
            }
            return basicDataDictionaryMapper.saveBatch(basicDataDictionaryBos);
        }

        // 编号不可更新
        basicDataDictionaryBo.setCode(null);
        return basicDataDictionaryMapper.updateById(basicDataDictionaryBo);
    }

    @Override
    public boolean findByCode(String code) {
        LambdaQueryWrapper<BasicDataDictionaryBo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BasicDataDictionaryBo::getCode, code);
        BasicDataDictionaryBo basicDataDictionaryBo = basicDataDictionaryMapper.selectOne(wrapper);
        return !ObjectUtils.isEmpty(basicDataDictionaryBo);
    }

    /**
     * 根据code查询一层子数据
     */
    @Override
    public Map<String, List<BasicDataDictionaryVo>> findByPidCode(String pidCode, Boolean isRole) {
        UserByRoleDto userByRoleDto = SecurityUtils.getUserByRoleDto();

        List<String> list = Arrays.stream(pidCode.split(",")).toList();
        LambdaQueryWrapper<BasicDataDictionaryBo> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(BasicDataDictionaryBo::getPCode, list)
                .eq(BasicDataDictionaryBo::getStatus, EnableOrDisableEnum.ENABLE.value)
                .orderByDesc(BasicDataDictionaryBo::getSort);


        List<BasicDataDictionaryVo> basicDataDictionaryBos =
                MybatisPlusUtils.changeDataClass(basicDataDictionaryMapper.selectList(wrapper),
                        BasicDataDictionaryVo.class);

        if (isRole) {

            // 筛选可访问的数据字典
            basicDataDictionaryBos = basicDataDictionaryBos.stream().filter(v -> {
                if (VerifyUtils.isEmpty(v.getEditRoleId())) {
                    return true;
                }
                String[] roles = v.getEditRoleId().split(",");
                boolean flag = false;
                for (String role : roles) {
                    flag = userByRoleDto.getRoleIdList().contains(Integer.valueOf(role));
                    if (flag) {
                        break;
                    }
                }
                return flag;
            }).toList();
        }


        return basicDataDictionaryBos.stream().collect(Collectors.groupingBy(BasicDataDictionaryVo::getPCode));
    }



    /**
     * 查询字典
     */
    @Override
    public List<BasicDataDictionaryVo> listByDictionary(SearchDictionaryRequest searchDictRequest) {
        // 查询所有字典数据
        List<BasicDataDictionaryVo> dictionaryBoList = findDictByRoleIdList();
        return TreeUtils.getRoot(dictionaryBoList);
    }

    /**
     * 查询数据字典根据角色id
     */
    @Override
    public List<BasicDataDictionaryVo> findDictByRoleIdList() {
        List<BasicDataDictionaryBo> dictionaryBos = basicDataDictionaryMapper.selectList(null);
        dictionaryBos = dictionaryBos.stream().filter(v -> {
            final UserByRoleDto userByRoleDto = SecurityUtils.getUserByRoleDto();


            final String editRoleId = v.getEditRoleId();
            // 没有限制角色直接使用
            if (VerifyUtils.isEmpty(editRoleId)) {
                return true;
            }

            // 获取用户角色id
            List<Integer> roleIds = userByRoleDto.getUserBo().getRoleList().stream().map(RoleBo::getId).toList();
            final String[] rIds = editRoleId.split(",");
            for (String rId : rIds) {
                if (roleIds.contains(Integer.valueOf(rId))) {
                    return true;
                }
            }
            return false;

        }).toList();

        return MybatisPlusUtils.changeDataClass(dictionaryBos, BasicDataDictionaryVo.class);
    }


    /**
     * 删除字典
     */
    @Override
    public Integer deleteById(Integer id) {
        BasicDataDictionaryBo basicDataDictionaryBo = getById(id);
        if (VerifyUtils.isEmpty(basicDataDictionaryBo)) {
            GraceException.display("字典不存在");
        }
        // 确定是否有权限删除
        String roleIdStr = basicDataDictionaryBo.getEditRoleId();

        // 根据当前id有没有数据的pid是当前数据，有的话不能直接删除
        final LambdaQueryWrapper<BasicDataDictionaryBo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BasicDataDictionaryBo::getPid, basicDataDictionaryBo.getId());
        final Long count = basicDataDictionaryMapper.selectCount(wrapper);
        if (count > 0) {
            GraceException.display("该字典下有子字典，不能直接删除");
        }

        UserByRoleDto userByRoleDto = SecurityUtils.getUserByRoleDto();
        if (VerifyUtils.isNotEmpty(roleIdStr) && !userByRoleDto.getRoleList().contains(BasicKey.SUPER_ADMIN)) {
            // 当前是否可以该字典的角色id
            String[] roleIdList = roleIdStr.split(",");
            List<Integer> roleIds = userByRoleDto.getUserBo().getRoleList().stream().map(RoleBo::getId).toList();
            for (Integer roleId : roleIds) {
                if (!Arrays.asList(roleIdList).contains(roleId.toString())) {
                    GraceException.display("您没有权限删除该字典");
                }
            }
        }
        return basicDataDictionaryMapper.deleteById(id);
    }

    /**
     * 查询字典 根据id 查询
     */
    @Override
    public BasicDataDictionaryBo getById(Integer id) {
        LambdaQueryWrapper<BasicDataDictionaryBo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BasicDataDictionaryBo::getId, id).eq(BasicDataDictionaryBo::getStatus,
                EnableOrDisableEnum.ENABLE.value);
        return basicDataDictionaryMapper.selectOne(wrapper);
    }

}
